package com.wjk.cms.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.wjk.cms.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class CommonUtil {

    private static String PRIVATE_KEY = "Encl1nLDL5jbZl6NbS4J8X7O8EdQbFUp20200312";

    public static final String CHARSET_UTF8 = "UTF-8";

    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private static final String NONCE_STR_DATE_TIME_FORMAT = "yyMMddHHmmss";

    private static final String NONCE_STR_DATE_TIME_FORMAT_YYYY = "yyyyMMddHHmmss";

    private static final String ORDER_CODE_PREFIX = "WJK";

    public static String generateCodeAlphabetPart() {
        int a = ThreadLocalRandom.current().nextInt(24);
        int b = a + 3;
        return ALPHABET.substring(a, b);
    }
    public static String getToken(User user) {
        return JWT.create().withAudience(user.getId().toString()) // 将 user id 保存到 token 里面
                .sign(Algorithm.HMAC256(PRIVATE_KEY + user.getPassword())); // 以 password 作为 token 的密钥的一部分，从而在用户修改密码之后，该 token 会被失效
    }

    /**
     * 生成编码
     */
    public static String generateCode() {
        return generateCodeAlphabetPart() + System.currentTimeMillis();
    }

    /**
     * 生成订单编码
     */
    public static String generateOrderCode() {
        return ORDER_CODE_PREFIX + System.currentTimeMillis();
    }

    /**
     * 生成订单编码V2 - 编码中体现用户通道(ntc)和模块(store/vip/other)
     */
    public static String generateOrderCodeV2(String channel, String module) {
        return channel.toUpperCase() + "-" + module.toUpperCase() + "-" + System.currentTimeMillis();
    }

    /**
     * 生成赠品编码
     */
    public static String generateGiftCode() {
//        DateFormat df = new SimpleDateFormat("yyyyMMdd");
//        Calendar calendar = Calendar.getInstance();
//        String dateName = df.format(calendar.getTime());
        return  "0000"+getRandaAlphabet(6);
    }

    public static String getRandaAlphabet(int length)
    {

        String rev = "";
        Random f = new Random();
        for(int i=0;i<length;i++)
        {
            rev += ALPHABET.charAt(Math.abs(f.nextInt())%ALPHABET.length());
        }
        return rev;
    }

    /**
     * 生成随机数字符加数字
     * @param length
     * @return
     */
    public static String getRandString(int length)
    {
        String charList = "0123456789abcdefghijklmnopqrstuvwxyz";
        String rev = "";
        Random f = new Random();
        for(int i=0;i<length;i++)
        {
            rev += charList.charAt(Math.abs(f.nextInt())%charList.length());
        }
        return rev;
    }

    /**
     * 生成 nonce_str
     */
    public static String generateNonceStr() {
        return new SimpleDateFormat(NONCE_STR_DATE_TIME_FORMAT).format(new Date()) + randomNumber(6);
    }

    public static String generateNonceStrYear() {
        return new SimpleDateFormat(NONCE_STR_DATE_TIME_FORMAT_YYYY).format(new Date()) + randomNumber(6);
    }

    /**
     * 生成 out_trade_no
     */
    public static String generateKxbOutTradeNo() {
        return generateOrderCodeV2("kxb", "vip");
    }

    /**
     * 返回长度为length的随机数字
     */
    public static int randomNumber(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }

    /**
     * 返回当前的时间戳（秒级）
     */
    public static String getTimeStamp() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }

    /**
     * 获取IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        log.error(e.getMessage(), e);
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        return ipAddress;
    }

    /**
     * 获取项目的 base url (绝对)
     */
    public static String getBaseUrl(HttpServletRequest request) {
        return request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath());
    }

    /**
     * 返回以分为单位的金额
     */
    public static String getMoneyInFen(String moneyInYuan) {
        return new BigDecimal(moneyInYuan).multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_CEILING).toString();
    }

    /**
     * 返回以分为单位的金额
     */
    public static String getMoneyInFen(BigDecimal moneyInYuan) {
        return moneyInYuan.multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_CEILING).toString();
    }

    /**
     * 返回以元为单位的金额
     */
    public static String getMoneyInYuan(int moneyInFen) {
        return new BigDecimal(moneyInFen).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 过滤utf8mb4特有字符（例如微信昵称中的表情）
     */
    public static String cleanUtf8Mb4Characters(String raw) {
        if (StringUtils.isEmpty(raw)) {
            return "";
        }
        Pattern emoji = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        Matcher emojiMatcher = emoji.matcher(raw);
        if (emojiMatcher.find()) {
            return emojiMatcher.replaceAll("*");
        } else {
            return raw;
        }
    }

    public static Long parseLong(String str) {
        Long result = null;
        try {
            result = Long.valueOf(str);
        } catch (Exception e) {
        }
        return result;
    }

    public static boolean isPhone(String phone) {
        if (StringUtils.isNotEmpty(phone) && phone.length() == 11) {
            return Pattern.compile("^1(3|4|5|6|7|8|9)\\d{9}$").matcher(phone).matches();
        }
        return false;
    }

    public static BigDecimal parseBigDecimal(String str) {
        if (StringUtils.isEmpty(str)) {
            return BigDecimal.ZERO;
        }
        try {
            return new BigDecimal(str);
        } catch (Exception e) {
        }
        return BigDecimal.ZERO;
    }

    public static int parseInt(String str) {
        int result = 0;
        if (StringUtils.isEmpty(str)) {
            return result;
        }
        try {
            result = Integer.parseInt(str);
        } catch (Exception e) {
        }
        return result;
    }

}
